import L from "leaflet"

let retina = (window.devicePixelRatio || (window.screen.deviceXDPI / window.screen.logicalXDPI)) > 1
let templateRe = /\{ *([\w_-]+) *\}/g
function template(str, data) {
    return str.replace(templateRe, function (str, key) {
        let value = data[key]
        if (value === undefined) {
            throw new Error('No value provided for variable ' + str)

        } else if (typeof value === 'function') {
            value = value(data)
        }
        return value
    })
}
function extend(dest) {
    let i, j, len, src
    for (j = 1, len = arguments.length; j < len; j++) {
        src = arguments[j]
        for (i in src) {
            dest[i] = src[i]
        }
    }
    return dest
}
let t
var hex_chr = "0123456789abcdef"; function hex(num) { var str = ""; for (var j = 7; j >= 0; j--)str += hex_chr.charAt((num >> (j * 4)) & 0x0F); return str } function str2blks_SHA1(str) { var nblk = ((str.length + 8) >> 6) + 1; var blks = new Array(nblk * 16); for (var i = 0; i < nblk * 16; i++)blks[i] = 0; for (i = 0; i < str.length; i++)blks[i >> 2] |= str.charCodeAt(i) << (24 - (i % 4) * 8); blks[i >> 2] |= 0x80 << (24 - (i % 4) * 8); blks[nblk * 16 - 1] = str.length * 8; return blks } function add(x, y) { var lsw = (x & 0xFFFF) + (y & 0xFFFF); var msw = (x >> 16) + (y >> 16) + (lsw >> 16); return (msw << 16) | (lsw & 0xFFFF) } function rol(num, cnt) { return (num << cnt) | (num >>> (32 - cnt)) } function ft(t, b, c, d) { if (t < 20) return (b & c) | ((~b) & d); if (t < 40) return b ^ c ^ d; if (t < 60) return (b & c) | (b & d) | (c & d); return b ^ c ^ d } function kt(t) { return (t < 20) ? 1518500249 : (t < 40) ? 1859775393 : (t < 60) ? -1894007588 : -899497514 } function calcSHA1(str) { var x = str2blks_SHA1(str); var w = new Array(80); var a = 1732584193; var b = -271733879; var c = -1732584194; var d = 271733878; var e = -1009589776; for (var i = 0; i < x.length; i += 16) { var olda = a; var oldb = b; var oldc = c; var oldd = d; var olde = e; for (var j = 0; j < 80; j++) { if (j < 16) w[j] = x[i + j]; else w[j] = rol(w[j - 3] ^ w[j - 8] ^ w[j - 14] ^ w[j - 16], 1); t = add(add(rol(a, 5), ft(j, b, c, d)), add(add(e, w[j]), kt(j))); e = d; d = c; c = rol(b, 30); b = a; a = t } a = add(a, olda); b = add(b, oldb); c = add(c, oldc); d = add(d, oldd); e = add(e, olde) } return hex(a) + hex(b) + hex(c) + hex(d) + hex(e) }

let tileLayerCALCSHA1 = L.TileLayer.extend({
    options: { codeArr: [0, 1, 2, 3, 4, 5] },
    getTileUrl: function (coords) {
        let data = {
            r: retina ? '@2x' : '',
            s: this._getSubdomain(coords),
            x: coords.x,
            y: coords.y,
            z: this._getZoomForUrl()
        }
        if (this._map && !this._map.options.crs.infinite) {
            let invertedY = this._globalTileRange.max.y - coords.y
            if (this.options.tms) {
                data['y'] = invertedY
            }
            data['-y'] = invertedY
        }

        let hashX = calcSHA1(String(data.x))
        let hashY = calcSHA1(String(data.y))
        let strx = '', stry = ''
        this.options.codeArr.forEach(function (pa) {
            strx += hashX[pa]
            stry += hashY[pa]
        })
        data['x'] = strx
        data['y'] = stry
        return template(this._url, extend(data, this.options))
    }
})
export default tileLayerCALCSHA1